package com.meiyuetao.myt.customer.service;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import lab.s2jh.ctx.DynamicConfigService;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.meiyuetao.myt.core.constant.MessageStateEnum;
import com.meiyuetao.myt.customer.dao.SmsDetailLogDao;
import com.meiyuetao.myt.customer.dao.SmsLogDao;
import com.meiyuetao.myt.customer.entity.SmsDetailLog;
import com.meiyuetao.myt.customer.entity.SmsDetailLog.SmsDetailChannelEnum;
import com.meiyuetao.myt.customer.entity.SmsLog;

@Service("threeTongSmsService")
@Transactional
public class ThreeTongSmsService extends SmsService {

    @Value("${sms.userName}")
    private String userName; // 用户名
    @Value("${sms.password}")
    private String password; // 密码
    private String sign = ""; // 短信内容
    private String msgid = "";
    private String subcode = "";
    public String sendtime = "";
    // public static String url="http://3tong.net/http/sms/Submit"; //无限通使用地址
    @Value("${sms.url}")
    private String url;
    @Autowired
    private SmsDetailLogDao smsDetailLogDao;
    @Autowired
    private SmsLogDao smsLogDao;
    @Autowired
    private DynamicConfigService dynamicConfigService;

    @Override
    protected Boolean bizSend(String phone, String content, SmsLog smsLog) {
        sign = dynamicConfigService.getString("cfg.sms.sign", "【美月淘】");
        // String url = "http://3tong.net/http/sms/Submit";
        String resp = null;
        if (StringUtils.isNotBlank(phone) && StringUtils.isNotBlank(content)) {
            Map<String, String> params = new LinkedHashMap<String, String>();
            ThreeTongSmsService docXml = new ThreeTongSmsService();
            String message = docXml.DocXml(userName, MD5Encode(password), msgid, phone, content, sign, subcode, sendtime);
            params.put("message", message);
            resp = doPost(url, params);
            String statu = StringUtils.substringBetween(resp, "<result>", "</result>");

            SmsDetailLog smsDetailLog = new SmsDetailLog();
            smsDetailLog.setContent(content);
            smsDetailLog.setMobile(phone);
            smsDetailLog.setSendTime(new Date());
            smsDetailLog.setSmsLog(smsLog);
            smsDetailLog.setSmsChannel(SmsDetailChannelEnum.STONG);
            String desc = StringUtils.substringBetween(resp, "<desc>", "</desc>");
            smsLogDao.save(smsLog);
            smsDetailLog.setMemo(desc);
            if (!"0".equals(statu)) {
                smsDetailLog.setState(MessageStateEnum.OK);
                smsDetailLog.setSmsLog(smsLog);
                smsDetailLogDao.save(smsDetailLog);
                return false;
            } else {
                smsDetailLog.setState(MessageStateEnum.OK);
                smsDetailLog.setSmsLog(smsLog);
                smsDetailLogDao.save(smsDetailLog);
                return true;
            }

        } else {
            return false;
        }

    }

    public class SMSInvalidException extends java.lang.Exception {
        public SMSInvalidException(String message) {
            super(message);
        }
    }

    // 状态报告
    public void getReport() {
        // String url = "http://3tong.net/http/sms/Submit";
        Map<String, String> params = new LinkedHashMap<String, String>();
        String message = "<?xml version='1.0' encoding='UTF-8'?><message>" + "<account>" + userName + "</account>" + "<password>" + MD5Encode(password) + "</password>"
                + "<msgid></msgid><phone>18221177661</phone></message>";
        params.put("message", message);
        String resp = doPost(url, params);

    }

    // MD5加密函数
    private String MD5Encode(String sourceString) {
        String resultString = null;
        try {
            resultString = new String(sourceString);
            MessageDigest md = MessageDigest.getInstance("MD5");
            resultString = byte2hexString(md.digest(resultString.getBytes()));
        } catch (Exception ex) {
        }
        return resultString;
    }

    private String byte2hexString(byte[] bytes) {
        StringBuffer bf = new StringBuffer(bytes.length * 2);
        for (int i = 0; i < bytes.length; i++) {
            if ((bytes[i] & 0xff) < 0x10) {
                bf.append("0");
            }
            bf.append(Long.toString(bytes[i] & 0xff, 16));
        }
        return bf.toString();
    }

    // 查询余额
    public String getBalance() {
        // String url = "http://3tong.net/http/sms/Submit";
        Map<String, String> params = new LinkedHashMap<String, String>();
        String message = "<?xml version='1.0' encoding='UTF-8'?><message><account>" + userName + "</account>" + "<password>" + MD5Encode(password) + "</password></message>";
        params.put("message", message);

        String resp = doPost(url, params);
        return resp;
    }

    // 获取上行
    /*
     * private static void getSms() {
     * 
     * Map<String, String> params = new LinkedHashMap<String, String>(); String
     * message = "<?xml version='1.0' encoding='UTF-8'?><message><account>" +
     * userName + "</account>" + "<password>" + MD5Encode(password) +
     * "</password></message>"; params.put("message", message);
     * 
     * String resp = doPost(url, params); System.out.println(resp); }
     */
    /**
     * 执行一个HTTP POST请求，返回请求响应的HTML
     * 
     * @param url
     *            请求的URL地址
     * @param params
     *            请求的查询参数,可以为null
     * @return 返回请求响应的HTML
     */
    private String doPost(String url, Map<String, String> params) {
        String response = null;
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        // HttpClient
        CloseableHttpClient client = httpClientBuilder.build();
        HttpPost httpPost = new HttpPost(url);
        List<NameValuePair> formparams = new ArrayList<NameValuePair>();
        UrlEncodedFormEntity entity;
        // 设置Post数据
        if (!params.isEmpty()) {
            for (Entry<String, String> entry : params.entrySet()) {
                formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }
        }
        try {
            entity = new UrlEncodedFormEntity(formparams, "UTF-8");
            httpPost.setEntity(entity);
            HttpResponse httpResponse;
            // post请求
            httpResponse = client.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            if (httpEntity != null) {
                response = EntityUtils.toString(httpEntity, "UTF-8");

            }
            client.close();
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return response;
    }

    /**
     * 使用document 对象封装XML
     * 
     * @param userName
     * @param pwd
     * @param id
     * @param phone
     * @param contents
     * @param sign
     * @param subcode
     * @param sendtime
     * @return
     */
    private String DocXml(String userName, String pwd, String msgid, String phone, String contents, String sign, String subcode, String sendtime) {
        Document doc = DocumentHelper.createDocument();
        doc.setXMLEncoding("UTF-8");
        Element message = doc.addElement("response");
        Element account = message.addElement("account");
        account.setText(userName);
        Element password = message.addElement("password");
        password.setText(pwd);
        Element msgid1 = message.addElement("msgid");
        msgid1.setText(msgid);
        Element phones = message.addElement("phones");
        phones.setText(phone);
        Element content = message.addElement("content");
        content.setText(contents);
        Element sign1 = message.addElement("sign");
        sign1.setText(sign);
        Element subcode1 = message.addElement("subcode");
        subcode1.setText(subcode);
        Element sendtime1 = message.addElement("sendtime");
        sendtime1.setText(sendtime);
        return message.asXML();
        // System.out.println(message.asXML());

    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getSign() {
        return sign;
    }

    public void setSign(String sign) {
        this.sign = sign;
    }

    public String getMsgid() {
        return msgid;
    }

    public void setMsgid(String msgid) {
        this.msgid = msgid;
    }

    public String getSubcode() {
        return subcode;
    }

    public void setSubcode(String subcode) {
        this.subcode = subcode;
    }

    public String getSendtime() {
        return sendtime;
    }

    public void setSendtime(String sendtime) {
        this.sendtime = sendtime;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

}
